`include "common_header.verilog"
//  *************************************************************************
//  File : bip_error_count_single_lane.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2009 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Denis Poverennyy
//  info@morethanip.com
//  *************************************************************************
//  Description : Implement the 16-bit BIP8 error counters for each with clear on read.
//  Version     : $Id: bip_error_count_single_lane.v,v 1.3 2011/11/15 18:03:37 dp Exp $
//  *************************************************************************

module bip_error_count_single_lane (
   
   reset_rx_clk,
   reset_reg_clk,
   rx_clk,
   reg_clk,
   sw_reset,
   bip8_stat,
   reg_rd,
   bip_cnt_rdata);
   
   
input   reset_rx_clk;           //  Asynchronous Reset - line clock Domain
input   reset_reg_clk;          //  Asynchronous Reset - reg_clk Domain
input   rx_clk;                 //  XL/CGMII Receive Clock
input   reg_clk;                //  Register Interface Clock
input   sw_reset;               //  SW reset
input   bip8_stat;              //  BIP-8 error status
input   reg_rd;                 //  reading
output   [15:0] bip_cnt_rdata;  //  register read data


reg     [15:0]  bip_cnt_rdata; 
reg             clear_bip_err_cnt; 
wire            bip_err_s0; 
reg             bip_err_d; 
wire            bip_err_s; 
wire    [16:0]  next_bip_err_cnt; 
reg     [16:0]  bip_err_cnt; 
wire            reg_rd_in_prog; 
reg             reg_rd_r; 

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_1
   if (reset_reg_clk == 1'b 1)
      begin
      reg_rd_r <= 1'b 0;	
      end
   else
      begin
      reg_rd_r <= reg_rd;	
      end
   end

assign reg_rd_in_prog = reg_rd | reg_rd_r; 


redge_ckxing U_BIP_ERR_SYNC (
          .reset(reset_rx_clk),
          .clk(rx_clk),
          .sig(bip8_stat),
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(bip_err_s0));


assign bip_err_s = (bip_err_s0 | bip_err_d) & ~reg_rd_in_prog; 


assign next_bip_err_cnt = bip_err_cnt + {16'b 0000000000000000, bip_err_s}; 


always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_2
   if (reset_reg_clk == 1'b 1)
      begin
      bip_err_d         <= 1'b 0;	
      bip_err_cnt       <= {17{1'b 0}};	
      bip_cnt_rdata     <= {16{1'b 0}};	
      end
   else
      begin
      if (bip_err_s0 == 1'b 1 & reg_rd_in_prog == 1'b 1)
         begin
         bip_err_d <= 1'b 1;	
         end
      else if (reg_rd_in_prog == 1'b 0 )
         begin
         bip_err_d <= 1'b 0;	
         end
      if (clear_bip_err_cnt == 1'b 1 & bip_err_s == 1'b 0 | sw_reset == 1'b 1)
         begin
         bip_err_cnt <= {17{1'b 0}};	
         end
      else if (clear_bip_err_cnt == 1'b 1 & bip_err_s == 1'b 1 )        //  do not miss count during read
         begin
         bip_err_cnt <= {16'b 0000000000000000, bip_err_s};	
         end
      else if (bip_err_s == 1'b 1 & bip_err_cnt[16] != 1'b 1 )
         begin
         bip_err_cnt <= next_bip_err_cnt;	
         end
      if (bip_err_cnt[16] == 1'b 1)
         begin
         bip_cnt_rdata <= 16'b 1111111111111111;	
         end
      else
         begin
         bip_cnt_rdata <= bip_err_cnt[15:0];	
         end
      end
   end



//  bip_err_cnt read done
// 
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_3
   if (reset_reg_clk == 1'b 1)
      begin
      clear_bip_err_cnt <= 1'b 0;	
      end
   else
      begin
      if (reg_rd == 1'b 0 & reg_rd_r == 1'b 1)
         begin
         clear_bip_err_cnt <= 1'b 1;	
         end
      else
         begin
         clear_bip_err_cnt <= 1'b 0;	
         end
      end
   end


endmodule // module bip_error_count_single_lane

